﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace app.scode.redo
{
    public class scode
    {
        #region struct
        public char start;			// 1	报文开始符号，固定为’{’															char	1	0	
        public int length;		// 2	数据长度，除报文开始结束符号和校验和之外的其它所有字节（2~19）之和（本报文为52）	int	4	1	
        public string stryardCod;
        public string strequipCod;
        public char[] yardCod;	    // 3	码头编码,4																			char	4	5
        public char[] equipCod;	// 4	设备编号,4																		char	4	9
        public short type;			// 5	设备类型，1：轮胎吊，2：保留，3：桥吊，-1无效										short	2	13
        public int dataTime;		// 6	数据采集时间，1970年0月0日0时0分0秒到当前时间的秒数									int	4	15
        public int off;			// 7	小车位移，单位：毫米，-1000000无效													int	4	19	
        public int sheight;		// 8	海测举升高度，单位：毫米，-1000000无效												int	4	23
        public int lheight;		// 9	路侧举升高度, 单位:毫米, -1000000无效												int    4   27
        public short lspace;		// 10	双吊具左间距，单位：毫米，-1000000无效												int	2	31	
        public short rspace;		// 11	双吊具右间距，单位：毫米，-1000000无效												int	2	33	
        public int speed;			// 12	小车速度，单位：毫米/秒 -1000000无效												int	4	35
        public short ssize;		// 13	海侧抓具尺寸，取值范围：20、40、45、22（20英尺双箱）、44（40英尺双箱）、-1无效		short	2	39	
        public short lsize;		// 14	路侧抓具尺寸，取值范围：20、40、45、22（20英尺双箱）、44（40英尺双箱）、-1无效		short	2	41	
        public short dir;			// 15	大车行走方向，取值范围：0、45、90、-1无效											short	2	43
        public short glFlag;		// 16	归零信号，1归零，0未到归零，-1无效													short	2	45
        public short sjjzlFlag;	// 17	海侧抓具着陆信号，1着陆，0未着陆，-1无效											short	2	47	
        public short ljjzlFlag;	// 18	路侧抓具着陆信号，1着陆，0未着陆，-1无效											short	2	49	
        public short glydFlag;		// 19	滚轮运动信号，1静止，0运行，-1无效													short	2	51	
        public short sjjkbFlag;	// 20	海测抓具开闭锁信号，1闭锁，0开锁，-1无效											short	2	53
        public short ljjkbFlag;	// 21	路侧抓具开闭锁信号，1闭锁，0开锁，-1无效											short	2	55
        public short jsFlag;		// 22	举升运动信号，1制动，0运行，-1无效													short	2	57
        public short spFlag;		// 23	小车水平运动信号，1制动，0运行，-1无效												short	2	59
        public short dcFlag;		// 24	大车运动信号，1制动，0运行，-1无效													short	2	61
        public char jy;			// 25	校验和，除报文开始结束符号和校验和之外的其它所有字节（2~19）按位异或				char	1	63
        public char end;			// 26	报文结束符号，固定为’}’															char	1	64
        #endregion
        //为了保险起见还是存下原始byte数组
        public scode()
        {
            yardCod = new char[4];
            equipCod = new char[4];
        }
        /// <summary>
        /// 获取所有数据
        /// </summary>
        /// <param name="data">将data设置为数据流</param>
        /// <param name="check">是否校验，默认为false</param>
        /// <returns></returns>
        public bool getdata(byte[] data,bool check = false)
        {
            //使用stream流读取，省点力气
            if (data.Length != 65) return false; 
            using(MemoryStream sr = new MemoryStream(data))
            {
                using(BinaryReader br = new BinaryReader(sr))
                {
                    start = br.ReadChar();
                    length = br.ReadInt32();
                    //if (data.Length != length + 3) return false;
                    yardCod = br.ReadChars(4);
                    equipCod = br.ReadChars(4);
                    type = br.ReadInt16();
                    dataTime = br.ReadInt32();
                    off = br.ReadInt32();
                    sheight = br.ReadInt32();
                    lheight = br.ReadInt32();
                    lspace = br.ReadInt16();
                    rspace = br.ReadInt16();
                    speed = br.ReadInt32();
                    ssize = br.ReadInt16();
                    lsize = br.ReadInt16();
                    dir = br.ReadInt16();
                    glFlag = br.ReadInt16();
                    sjjzlFlag = br.ReadInt16();
                    ljjzlFlag = br.ReadInt16();
                    glydFlag = br.ReadInt16();
                    sjjkbFlag = br.ReadInt16();
                    ljjkbFlag = br.ReadInt16();
                    jsFlag = br.ReadInt16();
                    spFlag = br.ReadInt16();
                    dcFlag = br.ReadInt16();
                    jy = br.ReadChar();
                    end = br.ReadChar();
                    stryardCod = new string(yardCod);
                    strequipCod = new string(equipCod);
                }
            }
            if (check)
            {
                byte cdata = 0;
                int len = 65;
                for (int i = 1; i < len - 2; i++)
                {
                    cdata ^= data[i];
                }
                return (cdata == data[len - 2]);
            }
            return true;
        }
        /*
        public long GetHeight(bool ReviseType,int posMax,int posMin)
        {	
            long midPos = ( posMax + posMin ) / 2;
	if( ReviseType )
	{
		//通过加速度进行计算
		//假设速度是变化的
		long curHeight = 0;
		long preHeight = 0;
		long firstHeight = 0;

		//速度转换成厘米
		double curSpeed = speed / 10.0;
		double preSpeed = m_preData.speed / 10.0;
		double firstSpeed = m_firstData.speed / 10.0;
		
		float spanTime = (curData.dataTime - m_preData.dataTime) * 1.0f;
		
		long posspan = abs ( ( posMax + posMin ) / 2 - curData.off );		//计算小车从现在的位置到中点的距离
		if ( curData.sjjkbFlag )	//如果是海侧,就用海侧的来计算,如果两个都是闭锁状态,就用海侧的计算
		{
			curHeight = curData.sheight;
			preHeight = m_preData.sheight;
			firstHeight = m_firstData.sheight;
		}else						//否则就用路侧的计算
		{
			curHeight = curData.lheight;
			preHeight = m_preData.lheight;
			firstHeight = m_firstData.lheight;
		}
		//加速度公式
		//S=1/2a*t*t;
		//S=v*t+1/2a*t*t
		if ( spanTime <= 0 )	//如果时间是0,就直接返回当前高度
			return curHeight;
		double xa = ( curSpeed * 1.0 - preSpeed ) / spanTime;
		double ya = ( ( curHeight - preHeight ) - ( preHeight - firstHeight ) ) * 1.0 / ( spanTime * spanTime );

		double yv1 = ( curHeight - preHeight - 1/2 * ya * spanTime * spanTime ) / spanTime;

		double xt = 0.0;
		xt = sqrt( xa * 2 * posspan );	//只计算一半路程的时间
		
		double reviseHeight = yv1 * xt + 1 / 2 * ya * spanTime * spanTime;
		curHeight = (long)reviseHeight + curHeight;
		return curHeight;
	}else
	{
		//假设所有速度都是匀速的
		long curHeight = 0;
		long preheight = 0;
		double curSpeed = curData.speed / 10.0;		//转换成厘米
		long posspan = abs ( ( posMax + posMin ) / 2 - curData.off );		//计算小车从现在的位置到中点的距离
		float spanTime = (curData.curTime - m_preData.curTime) / 1000.0f;
		
		if ( curData.sjjkbFlag && curData.ljjkbFlag )
		{
			curHeight = curData.sheight;
			preheight = m_preData.sheight;
		}
		if ( curData.sjjkbFlag )
		{
			//计算一下小车从开始拍照点走到两个点中间位置时的时间,然后用高度变化的速度乘以这个时间,然后与原来高度相加(正负号在),得到调整后的高度
			curHeight = curData.sheight;
			preheight = m_preData.sheight;

		}else if ( curData.ljjkbFlag )
		{
			curHeight = curData.lheight;
			preheight = m_preData.lheight;
		}
		if ( spanTime <= 0 )
		{
			curHeight = min( curData.sheight, curData.lheight );
		}else
		{
			//计算经过的时间,然后推算出高度
			if ( curSpeed <= 0 ) 
				return curHeight;
			curHeight = int( curHeight + ( curHeight - preheight )
				/ spanTime * 1.0f * ( posspan  / curSpeed ));
		}
		return curHeight;
	}

	return 0;

        }
         * */
    }
    static public class GLOBAL
    {
        //static public bool isOn = false;
        //大车类
        static public class MOVING 
        {
            //是否正在移动
            static public bool IS_MOVING = false;
            //移动至今开始时间
            static public int RUNNING_Delay = 0;
            static public int Begin_DateTime = 0;
            static public void reset()
            {
                IS_MOVING = false;
                RUNNING_Delay = 0;
                Begin_DateTime = 0;
            }
        }
        //常量类
        static public class CONST
        {
            static public int LONG_ERROR_DATA = -1000000;
            static public int SHORT_ERROR_DATA = -1;
            static public int BREAK_TIMER = 1000;
            static public int DISTANCE_OUT = -8000;
            static public int DISTANCE_IN = 8000;
            static public int BREAK_TIMER_CRAIN = 1000;
        }
        static public scode Seapredata = new scode();
        static public scode Landpredata = new scode();

        static public bool SeaIsOff = false;
        static public bool LandIsOff = false;
        static public class drawEvents
        {
            static public int CrainWidth = 20;
        }
        public enum Flag
        {
            on = 0,
            off = 1,
            undefined = -1,
        }
    }

}
